sched/wqueue, libs/libc/wqueue, configs: Remove work queue polling delay to simplify the code logic and save the power.
This commit is contained in:
parent
631071cded
commit
7e63b0b288
@ -12,7 +12,7 @@
|
||||
<h1><big><font color="#3c34ec">
|
||||
<i>NuttX RTOS Porting Guide</i>
|
||||
</font></big></h1>
|
||||
<p>Last Updated: August 10, 2018</p>
|
||||
<p>Last Updated: August 25, 2018</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -3009,10 +3009,18 @@ typedef uint32_t wdparm_t;
|
||||
The dedicated high-priority work queue is intended to handle delayed processing from interrupt handlers. This work queue is required for some drivers but, if there are no complaints, can be safely disabled. The high priority worker thread also performs garbage collection -- completing any delayed memory deallocations from interrupt handlers. If the high-priority worker thread is disabled, then that clean up will be performed either by (1) the low-priority worker thread, if enabled, and if not (2) the IDLE thread instead (which runs at the lowest of priority and may not be appropriate if memory reclamation is of high priority)
|
||||
</p>
|
||||
<p><b>Device Driver Bottom Half</b>.
|
||||
The higher priority worker thread is intended to serve as the <i>bottom half</i> for device drivers. As a consequence it must run at a very high, fixed priority rivalling the priority of the interrupt handler itself. Typically, the high priority work queue should be the highest priority thread in your system (the default priority is 224).
|
||||
The high-priority worker thread is intended to serve as the <i>bottom half</i> for device drivers. As a consequence it must run at a very high, fixed priority rivalling the priority of the interrupt handler itself. Typically, the high priority work queue should be the highest priority thread in your system (the default priority is 224).
|
||||
</p>
|
||||
<p>
|
||||
<b>Thread Pool</b>.
|
||||
The work queues can be configured to support multiple, low-priority threads. This is essentially a <i>thread pool</i> that provides multi-threaded servicing of the queue work. This breaks the strict serialization of the "queue" (and hence, the work queue is no longer a queue at all).
|
||||
</p>
|
||||
<p>
|
||||
Multiple worker threads are required to support, for example, I/O operations that stall waiting for input. If there is only a single thread, then the entire work queue processing would stall in such cases.
|
||||
Such behavior is necessary to support asynchronous I/O, AIO, for example.
|
||||
</p>
|
||||
<p><b>Compared to the Low Priority Kernel Work Queue</b>.
|
||||
For less critical, lower priority, application oriented worker thread support, 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 <i>priority inheritance</i> (if <config> CONFIG_PRIORITY_INHERITANCE</code> is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client.
|
||||
For less critical, lower priority, application oriented worker thread support, 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 <i>priority inheritance</i> (if <code>CONFIG_PRIORITY_INHERITANCE=y</code> is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client.
|
||||
</p>
|
||||
<p>
|
||||
<b>Configuration Options</b>.
|
||||
@ -3021,11 +3029,12 @@ typedef uint32_t wdparm_t;
|
||||
<li><code>CONFIG_SCHED_HPWORK</code>.
|
||||
Enables the hight priority work queue.
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_HPNTHREADS</code>.
|
||||
The number of threads in the high-priority queue's thread pool. Default: 1
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_HPWORKPRIORITY</code>.
|
||||
The execution priority of the high-priority worker thread. Default: 224
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_HPWORKPERIOD</code>.
|
||||
How often the worker thread re-checks for work in units of microseconds. This work period is really only necessary if the high priority thread is performing periodic garbage collection. The worker thread will be awakened immediately with it is queued work to be done. If the high priority worker thread is performing garbage collection, then the default is 50*1000 (50 MS). Otherwise, if the lower priority worker thread is performing garbage collection, the default is 100*1000.
|
||||
<li><code>CONFIG_SCHED_HPWORKSTACKSIZE</code>.
|
||||
The stack size allocated for the worker thread in bytes. Default: 2048.
|
||||
</li>
|
||||
@ -3047,30 +3056,19 @@ typedef uint32_t wdparm_t;
|
||||
</p>
|
||||
<p>
|
||||
<b>Compared to the High Priority Work Queue</b>.
|
||||
The lower priority work queue runs at a lower priority than the high priority work queue, of course, and so is inappropriate to serve as a driver <i>bottom half</i>. The lower priority work queue has the other advantages, however, that make it better suited for some tasks:
|
||||
The lower priority work queue runs at a lower priority than the high priority work queue, of course, and so is inappropriate to serve as a driver <i>bottom half</i>.
|
||||
It is, otherwise, very similar to the high priority work queue and most of the discussion above for the high priority work queue applies equally here.
|
||||
The lower priority work queue does have one important, however, that make it better suited for some tasks:
|
||||
</p>
|
||||
<p><b>Priority Inheritance</b>.
|
||||
The lower priority worker thread(s) support <i>priority inheritance</i> (if <config> CONFIG_PRIORITY_INHERITANCE</code> is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client.
|
||||
</p>
|
||||
<blockquote>
|
||||
<b>NOTE:</b> This priority inheritance feature is not automatic. The lower priority worker thread will always a fixed priority unless additional logic implements that calls <code>lpwork_boostpriority()</code> to raise the priority of the lower priority worker thread (typically called before scheduling the work) and then calls the matching <code>lpwork_restorepriority()</code> 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.
|
||||
</blockquote>
|
||||
<p>
|
||||
The higher priority worker thread, on the other hand, is intended to serve as the <i>bottom half</i> for device drivers. As a consequence must run at a very high, fixed priority. Typically, it should be the highest priority thread in your system.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>Priority Inheritance</b>.
|
||||
The lower priority worker thread(s) support <i>priority inheritance</i> (if <config> CONFIG_PRIORITY_INHERITANCE</code> is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client.
|
||||
</p>
|
||||
<blockquote>
|
||||
<b>NOTE:</b> This priority inheritance feature is not automatic. The lower priority worker thread will always a fixed priority unless additional logic implements that calls <code>lpwork_boostpriority()</code> to raise the priority of the lower priority worker thread (typically called before scheduling the work) and then calls the matching <code>lpwork_restorepriority()</code> 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.
|
||||
</blockquote>
|
||||
<p>
|
||||
The higher priority worker thread, on the other hand, is intended to serve as the <i>bottom half</i> for device drivers. As a consequence must run at a very high, fixed priority. Typically, it should be the highest priority thread in your system.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>
|
||||
<b>Thread Pool</b>.
|
||||
The low-priority work queue can be configured to support multiple, low-priority threads. This is essentially a <i>thread pool</i> that provides multi-threaded servicing of the low-priority work thread. This breaks the strict serialization of the "queue" (and hence, the low-priority work queue is no longer a queue at all).
|
||||
</p>
|
||||
<p>
|
||||
Multiple worker threads are required to support, for example, I/O operations that stall waiting for input. If there is only a single thread, then the entire low-priority queue processing would stall in such cases. Such behavior is necessary to support asynchronous I/O, AIO, for example.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Configuration Options</b>.
|
||||
</p>
|
||||
@ -3079,16 +3077,13 @@ typedef uint32_t wdparm_t;
|
||||
If CONFIG_SCHED_LPWORK is selected then a lower-priority work queue will be enabled.
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_LPNTHREADS</code>.
|
||||
The number of thread in the low-priority queue's thread pool. Default: 1
|
||||
The number of threads in the low-priority queue's thread pool. Default: 1
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_LPWORKPRIORITY</code>.
|
||||
The minimum execution priority of the lower priority worker thread. The priority of the all worker threads start at this priority. If priority inheritance is in effect, the priority may be boosted from this level. Default: 50.
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_LPWORKPRIOMAX</code>.
|
||||
The maximum execution priority of the lower priority worker thread. Lower priority worker threads will be started at <code>CONFIG_SCHED_LPWORKPRIORITY</code> but their priority may be boosted due to priority inheritance. The boosted priority of the low priority worker thread will not, however, ever exceed<code>CONFIG_SCHED_LPWORKPRIOMAX</code>. This limit 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.
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_LPWORKPERIOD</code>.
|
||||
How often the lower priority worker thread checks for garbage collection in units of microseconds. Default: 50*1000 (50 MS).
|
||||
The maximum execution priority of the lower priority worker thread. Lower priority worker threads will be started at <code>CONFIG_SCHED_LPWORKPRIORITY</code> but their priority may be boosted due to priority inheritance. The boosted priority of the low priority worker thread will not, however, ever exceed <code>CONFIG_SCHED_LPWORKPRIOMAX</code>. This limit 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.
|
||||
</li>
|
||||
<li><code>CONFIG_SCHED_LPWORKSTACKSIZE</code>.
|
||||
The stack size allocated for the lower priority worker thread. Default: 2048.
|
||||
@ -3112,8 +3107,6 @@ typedef uint32_t wdparm_t;
|
||||
If CONFIG_LIB_USRWORK is also defined then the user-mode work queue will be enabled.
|
||||
<li><code>CONFIG_LIB_USRWORKPRIORITY</code>.
|
||||
The execution priority of the user-mode priority worker thread. Default: 100
|
||||
<li><code>CONFIG_LIB_USRWORKPERIOD</code>
|
||||
How often the lower priority worker thread is awakened in units of microseconds. Default: 100*1000 (100 MS).
|
||||
<li><code>CONFIG_LIB_USRWORKSTACKSIZE</code>.
|
||||
The stack size allocated for the lower priority worker thread. Default: 2048.
|
||||
</ul>
|
||||
|
@ -76,7 +76,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -67,7 +67,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -78,7 +78,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -94,7 +94,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -79,7 +79,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -96,7 +96,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -90,7 +90,6 @@ CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
|
@ -66,7 +66,6 @@ CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
|
@ -86,7 +86,6 @@ CONFIG_RTC_HIRES=y
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
|
@ -145,7 +145,6 @@ CONFIG_SCHED_ATEXIT=y
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_INSTRUMENTATION=y
|
||||
CONFIG_SCHED_INSTRUMENTATION_BUFFER=y
|
||||
|
@ -153,7 +153,6 @@ CONFIG_SCHED_ATEXIT=y
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_INSTRUMENTATION=y
|
||||
CONFIG_SCHED_INSTRUMENTATION_BUFFER=y
|
||||
|
@ -150,7 +150,6 @@ CONFIG_SCHED_ATEXIT=y
|
||||
CONFIG_SCHED_CHILD_STATUS=y
|
||||
CONFIG_SCHED_HAVE_PARENT=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_INSTRUMENTATION=y
|
||||
CONFIG_SCHED_INSTRUMENTATION_BUFFER=y
|
||||
|
@ -422,7 +422,6 @@ Configurations
|
||||
CONFIG_SCHED_WORKQUEUE=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=224
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=2048
|
||||
|
||||
CONFIG_MMCSD=y
|
||||
|
@ -114,7 +114,6 @@ CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RTC_ALARM=y
|
||||
CONFIG_RTC_DATETIME=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=20000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_ONEXIT=y
|
||||
CONFIG_SCHED_ONEXIT_MAX=4
|
||||
|
@ -63,7 +63,6 @@ CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RTC_ALARM=y
|
||||
CONFIG_RTC_DATETIME=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=20000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_ONEXIT=y
|
||||
CONFIG_SCHED_ONEXIT_MAX=4
|
||||
|
@ -67,7 +67,6 @@ CONFIG_RAM_SIZE=20480
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=100000
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=758
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
|
@ -110,7 +110,6 @@ CONFIG_SAMV7_SPI0=y
|
||||
CONFIG_SAMV7_UART3=y
|
||||
CONFIG_SAMV7_XDMAC=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
|
@ -118,7 +118,6 @@ CONFIG_SAMV7_SPI0=y
|
||||
CONFIG_SAMV7_UART3=y
|
||||
CONFIG_SAMV7_XDMAC=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SCHED_LPWORKPRIORITY=160
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
|
@ -56,7 +56,6 @@ CONFIG_RAM_SIZE=114688
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_HPWORKPERIOD=50000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
|
@ -62,7 +62,6 @@ CONFIG_RAM_SIZE=245760
|
||||
CONFIG_RAM_START=0x20010000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPERIOD=5000
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_HPWORKSTACKSIZE=1800
|
||||
CONFIG_SCHED_INSTRUMENTATION=y
|
||||
|
@ -1,7 +1,8 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/wqueue.h
|
||||
*
|
||||
* Copyright (C) 2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2011-2014, 2017-2018 Gregory Nutt. All rights
|
||||
* reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,11 +70,6 @@
|
||||
* thread pool. Default: 1
|
||||
* CONFIG_SCHED_HPWORKPRIORITY - The execution priority of the high-
|
||||
* priority worker thread. Default: 224
|
||||
* CONFIG_SCHED_HPWORKPERIOD - How often the worker thread checks for
|
||||
* work in units of microseconds. If the high priority worker thread is
|
||||
* performing garbage collection, then the default is 50*1000 (50 MS).
|
||||
* Otherwise, if the lower priority worker thread is performing garbage
|
||||
* collection, the default is 100*1000.
|
||||
* CONFIG_SCHED_HPWORKSTACKSIZE - The stack size allocated for the worker
|
||||
* thread. Default: 2048.
|
||||
* CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up
|
||||
@ -89,8 +85,6 @@
|
||||
* 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
|
||||
* priority worker thread. Default: 2048.
|
||||
*
|
||||
@ -102,8 +96,6 @@
|
||||
* user-mode work queue will be created.
|
||||
* CONFIG_LIB_USRWORKPRIORITY - The minimum execution priority of the lower
|
||||
* priority worker thread. Default: 100
|
||||
* CONFIG_LIB_USRWORKPERIOD - How often the lower priority worker thread
|
||||
* checks for work in units of microseconds. Default: 100*1000 (100 MS).
|
||||
* CONFIG_LIB_USRWORKSTACKSIZE - The stack size allocated for the lower
|
||||
* priority worker thread. Default: 2048.
|
||||
*/
|
||||
@ -156,14 +148,6 @@
|
||||
# define CONFIG_SCHED_HPWORKPRIORITY 224
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SCHED_HPWORKPERIOD
|
||||
# ifdef CONFIG_SCHED_LPWORK
|
||||
# define CONFIG_SCHED_HPWORKPERIOD (100*1000) /* 100 milliseconds */
|
||||
# else
|
||||
# define CONFIG_SCHED_HPWORKPERIOD (50*1000) /* 50 milliseconds */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SCHED_HPWORKSTACKSIZE
|
||||
# define CONFIG_SCHED_HPWORKSTACKSIZE CONFIG_IDLETHREAD_STACKSIZE
|
||||
# endif
|
||||
@ -203,10 +187,6 @@
|
||||
# error CONFIG_SCHED_LPWORKPRIORITY > CONFIG_SCHED_LPWORKPRIOMAX
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SCHED_LPWORKPERIOD
|
||||
# define CONFIG_SCHED_LPWORKPERIOD (50*1000) /* 50 milliseconds */
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SCHED_LPWORKSTACKSIZE
|
||||
# define CONFIG_SCHED_LPWORKSTACKSIZE CONFIG_IDLETHREAD_STACKSIZE
|
||||
# endif
|
||||
@ -231,10 +211,6 @@
|
||||
# define CONFIG_LIB_USRWORKPRIORITY 100
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_LIB_USRWORKPERIOD
|
||||
# define CONFIG_LIB_USRWORKPERIOD (100*1000) /* 100 milliseconds */
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_LIB_USRWORKSTACKSIZE
|
||||
# define CONFIG_LIB_USRWORKSTACKSIZE CONFIG_IDLETHREAD_STACKSIZE
|
||||
# endif
|
||||
|
@ -21,13 +21,6 @@ config LIB_USRWORKPRIORITY
|
||||
---help---
|
||||
The execution priority of the user-mode priority worker thread. Default: 100
|
||||
|
||||
config LIB_USRWORKPERIOD
|
||||
int "User mode worker thread period"
|
||||
default 100000
|
||||
---help---
|
||||
How often the lower priority worker thread checks for work in units
|
||||
of microseconds. Default: 100*1000 (100 MS).
|
||||
|
||||
config LIB_USRWORKSTACKSIZE
|
||||
int "User mode worker thread stack size"
|
||||
default 2048
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/wqueue/work_usrthread.c
|
||||
*
|
||||
* Copyright (C) 2009-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,6 +69,12 @@
|
||||
# define WORK_CLOCK CLOCK_REALTIME
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSTEM_TIME64
|
||||
# define WORK_DELAY_MAX UINT64_MAX
|
||||
#else
|
||||
# define WORK_DELAY_MAX UINT32_MAX
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
@ -130,7 +136,7 @@ void work_process(FAR struct usr_wqueue_s *wqueue)
|
||||
* in the work list.
|
||||
*/
|
||||
|
||||
next = wqueue->delay;
|
||||
next = WORK_DELAY_MAX;
|
||||
ret = work_lock();
|
||||
if (ret < 0)
|
||||
{
|
||||
@ -249,20 +255,19 @@ void work_process(FAR struct usr_wqueue_s *wqueue)
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the delay (in clock ticks) since we started the sampling */
|
||||
|
||||
elapsed = clock() - stick;
|
||||
if (elapsed < wqueue->delay && next > 0)
|
||||
if (next == WORK_DELAY_MAX)
|
||||
{
|
||||
/* How must time would we need to delay to get to the end of the
|
||||
* sampling period? The amount of time we delay should be the smaller
|
||||
* of the time to the end of the sampling period and the time to the
|
||||
* next work expiry.
|
||||
*/
|
||||
sigset_t set;
|
||||
|
||||
remaining = wqueue->delay - elapsed;
|
||||
next = MIN(next, remaining);
|
||||
/* Wait indefinitely until signaled with SIGWORK */
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGWORK);
|
||||
|
||||
sigwaitinfo(&set, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait awhile to check the work list. We will wait here until
|
||||
* either the time elapses or until we are awakened by a signal.
|
||||
* Interrupts will be re-enabled while we wait.
|
||||
@ -340,8 +345,6 @@ int work_usrstart(void)
|
||||
{
|
||||
/* Initialize work queue data structures */
|
||||
|
||||
g_usrwork.delay = CONFIG_LIB_USRWORKPERIOD / USEC_PER_TICK;
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
{
|
||||
/* Set up the work queue lock */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/libs/libc/wqueue.h
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2014, 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -61,7 +61,6 @@
|
||||
|
||||
struct usr_wqueue_s
|
||||
{
|
||||
uint32_t delay; /* Delay between polling cycles (ticks) */
|
||||
struct dq_queue_s q; /* The queue of pending work */
|
||||
pid_t pid; /* The task ID of the worker thread(s) */
|
||||
};
|
||||
|
@ -1339,17 +1339,6 @@ config SCHED_HPWORKPRIORITY
|
||||
priority worker thread can then be adjusted to match the highest
|
||||
priority client.
|
||||
|
||||
config SCHED_HPWORKPERIOD
|
||||
int "High priority worker thread period"
|
||||
default 100000 if SCHED_LPWORK
|
||||
default 50000 if !SCHED_LPWORK
|
||||
---help---
|
||||
How often the worker thread checks for work in units of microseconds.
|
||||
Default: If the high priority worker thread is performing garbage
|
||||
collection, then the default is 50*1000 (50 MS). Otherwise, if the
|
||||
lower priority worker thread is performing garbage collection, the
|
||||
default is 100*1000.
|
||||
|
||||
config SCHED_HPWORKSTACKSIZE
|
||||
int "High priority worker thread stack size"
|
||||
default 2048
|
||||
@ -1450,13 +1439,6 @@ config SCHED_LPWORKPRIOMAX
|
||||
the maximum priority of the lower priority work thread. Default:
|
||||
176
|
||||
|
||||
config SCHED_LPWORKPERIOD
|
||||
int "Low priority worker thread period"
|
||||
default 50000
|
||||
---help---
|
||||
How often the lower priority worker thread checks for work in units
|
||||
of microseconds. Default: 50*1000 (50 MS).
|
||||
|
||||
config SCHED_LPWORKSTACKSIZE
|
||||
int "Low priority worker thread stack size"
|
||||
default 2048
|
||||
|
@ -125,12 +125,9 @@ static int work_hpthread(int argc, char *argv[])
|
||||
{
|
||||
/* The other threads will perform work, waiting indefinitely until
|
||||
* signalled for the next work availability.
|
||||
*
|
||||
* The special value of zero for the poll period instructs work_process
|
||||
* to wait indefinitely until a signal is received.
|
||||
*/
|
||||
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_hpwork, 0, wndx);
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_hpwork, wndx);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -151,11 +148,11 @@ static int work_hpthread(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
/* Then process queued work. work_process will not return until: (1)
|
||||
* there is no further work in the work queue, and (2) the polling
|
||||
* period provided by g_hpwork.delay expires.
|
||||
* there is no further work in the work queue, and (2) signal is
|
||||
* triggered, or delayed work expires.
|
||||
*/
|
||||
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_hpwork, g_hpwork.delay, 0);
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_hpwork, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,10 +183,6 @@ int work_hpstart(void)
|
||||
pid_t pid;
|
||||
int wndx;
|
||||
|
||||
/* Initialize work queue data structures */
|
||||
|
||||
g_hpwork.delay = CONFIG_SCHED_HPWORKPERIOD / USEC_PER_TICK;
|
||||
|
||||
/* Don't permit any of the threads to run until we have fully initialized
|
||||
* g_hpwork.
|
||||
*/
|
||||
|
@ -124,12 +124,9 @@ static int work_lpthread(int argc, char *argv[])
|
||||
{
|
||||
/* The other threads will perform work, waiting indefinitely until
|
||||
* signalled for the next work availability.
|
||||
*
|
||||
* The special value of zero for the poll period instructs work_process
|
||||
* to wait indefinitely until a signal is received.
|
||||
*/
|
||||
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_lpwork, 0, wndx);
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_lpwork, wndx);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -147,11 +144,11 @@ static int work_lpthread(int argc, char *argv[])
|
||||
sched_garbage_collection();
|
||||
|
||||
/* Then process queued work. work_process will not return until:
|
||||
* (1) there is no further work in the work queue, and (2) the polling
|
||||
* period provided by g_lpwork.delay expires.
|
||||
* (1) there is no further work in the work queue, and (2) signal is
|
||||
* triggered, or delayed work expires.
|
||||
*/
|
||||
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_lpwork, g_lpwork.delay, 0);
|
||||
work_process((FAR struct kwork_wqueue_s *)&g_lpwork, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,10 +179,6 @@ int work_lpstart(void)
|
||||
pid_t pid;
|
||||
int wndx;
|
||||
|
||||
/* Initialize work queue data structures */
|
||||
|
||||
g_lpwork.delay = CONFIG_SCHED_LPWORKPERIOD / USEC_PER_TICK;
|
||||
|
||||
/* Don't permit any of the threads to run until we have fully initialized
|
||||
* g_lpwork.
|
||||
*/
|
||||
|
@ -68,6 +68,12 @@
|
||||
# define WORK_CLOCK CLOCK_REALTIME
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYSTEM_TIME64
|
||||
# define WORK_DELAY_MAX UINT64_MAX
|
||||
#else
|
||||
# define WORK_DELAY_MAX UINT32_MAX
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
@ -93,7 +99,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void work_process(FAR struct kwork_wqueue_s *wqueue, clock_t period, int wndx)
|
||||
void work_process(FAR struct kwork_wqueue_s *wqueue, int wndx)
|
||||
{
|
||||
volatile FAR struct work_s *work;
|
||||
worker_t worker;
|
||||
@ -109,10 +115,10 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, clock_t period, int wndx)
|
||||
* we process items in the work list.
|
||||
*/
|
||||
|
||||
next = period;
|
||||
next = WORK_DELAY_MAX;
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Get the time that we started this polling cycle in clock ticks. */
|
||||
/* Get the time that we started processing the queue in clock ticks. */
|
||||
|
||||
stick = clock_systimer();
|
||||
|
||||
@ -215,16 +221,16 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, clock_t period, int wndx)
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(CONFIG_SCHED_HPWORK) && CONFIG_SCHED_HPNTHREADS > 1) \
|
||||
|| (defined(CONFIG_SCHED_LPWORK) && CONFIG_SCHED_LPNTHREADS > 1)
|
||||
/* Value of zero for period means that we should wait indefinitely until
|
||||
* signalled. This option is used only for the case where there are
|
||||
* multiple worker threads. In that case, only one of the threads does
|
||||
* the poll... the others simple. In all other cases period will be
|
||||
* non-zero and equal to wqueue->delay.
|
||||
/* When multiple worker threads are created for this work queue, only
|
||||
* thread 0 (wndx = 0) will monitor the unexpired works.
|
||||
*
|
||||
* Other worker threads (wndx > 0) just process no-delay or expired
|
||||
* works, then sleep. The unexpired works are left in the queue. They
|
||||
* will be handled by thread 0 when it finishes current work and iterate
|
||||
* over the queue again.
|
||||
*/
|
||||
|
||||
if (period == 0)
|
||||
if (wndx > 0 || next == WORK_DELAY_MAX)
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
@ -238,31 +244,15 @@ void work_process(FAR struct kwork_wqueue_s *wqueue, clock_t period, int wndx)
|
||||
wqueue->worker[wndx].busy = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Get the delay (in clock ticks) since we started the sampling */
|
||||
/* Wait a while to check the work list. We will wait here until
|
||||
* either the time elapses or until we are awakened by a signal.
|
||||
* Interrupts will be re-enabled while we wait.
|
||||
*/
|
||||
|
||||
elapsed = clock_systimer() - stick;
|
||||
if (elapsed < period && next > 0)
|
||||
{
|
||||
/* How much time would we need to delay to get to the end of the
|
||||
* sampling period? The amount of time we delay should be the smaller
|
||||
* of the time to the end of the sampling period and the time to the
|
||||
* next work expiry.
|
||||
*/
|
||||
|
||||
remaining = period - elapsed;
|
||||
next = MIN(next, remaining);
|
||||
|
||||
/* Wait awhile to check the work list. We will wait here until
|
||||
* either the time elapses or until we are awakened by a signal.
|
||||
* Interrupts will be re-enabled while we wait.
|
||||
*/
|
||||
|
||||
wqueue->worker[wndx].busy = false;
|
||||
nxsig_usleep(next * USEC_PER_TICK);
|
||||
wqueue->worker[wndx].busy = true;
|
||||
}
|
||||
wqueue->worker[wndx].busy = false;
|
||||
nxsig_usleep(next * USEC_PER_TICK);
|
||||
wqueue->worker[wndx].busy = true;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
@ -74,7 +74,6 @@ struct kworker_s
|
||||
|
||||
struct kwork_wqueue_s
|
||||
{
|
||||
clock_t delay; /* Delay between polling cycles (ticks) */
|
||||
struct dq_queue_s q; /* The queue of pending work */
|
||||
struct kworker_s worker[1]; /* Describes a worker thread */
|
||||
};
|
||||
@ -86,7 +85,6 @@ struct kwork_wqueue_s
|
||||
#ifdef CONFIG_SCHED_HPWORK
|
||||
struct hp_wqueue_s
|
||||
{
|
||||
clock_t delay; /* Delay between polling cycles (ticks) */
|
||||
struct dq_queue_s q; /* The queue of pending work */
|
||||
|
||||
/* Describes each thread in the high priority queue's thread pool */
|
||||
@ -102,7 +100,6 @@ struct hp_wqueue_s
|
||||
#ifdef CONFIG_SCHED_LPWORK
|
||||
struct lp_wqueue_s
|
||||
{
|
||||
clock_t delay; /* Delay between polling cycles (ticks) */
|
||||
struct dq_queue_s q; /* The queue of pending work */
|
||||
|
||||
/* Describes each thread in the low priority queue's thread pool */
|
||||
@ -180,7 +177,6 @@ int work_lpstart(void);
|
||||
*
|
||||
* Input Parameters:
|
||||
* wqueue - Describes the work queue to be processed
|
||||
* period - The polling period in clock ticks
|
||||
* wndx - The worker thread index
|
||||
*
|
||||
* Returned Value:
|
||||
@ -188,7 +184,7 @@ int work_lpstart(void);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void work_process(FAR struct kwork_wqueue_s *wqueue, clock_t period, int wndx);
|
||||
void work_process(FAR struct kwork_wqueue_s *wqueue, int wndx);
|
||||
|
||||
#endif /* CONFIG_SCHED_WORKQUEUE */
|
||||
#endif /* __SCHED_WQUEUE_WQUEUE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user