From 7e63b0b28857acf50dcfb48aa6ab920e5b55f949 Mon Sep 17 00:00:00 2001 From: xuanlin Date: Sat, 25 Aug 2018 14:58:07 -0600 Subject: [PATCH] sched/wqueue, libs/libc/wqueue, configs: Remove work queue polling delay to simplify the code logic and save the power. --- Documentation/NuttxPortingGuide.html | 63 +++++++++---------- .../b-l475e-iot01a/spirit-6lowpan/defconfig | 1 - .../b-l475e-iot01a/spirit-starhub/defconfig | 1 - .../b-l475e-iot01a/spirit-starpoint/defconfig | 1 - .../clicker2-stm32/mrf24j40-6lowpan/defconfig | 1 - .../clicker2-stm32/mrf24j40-starhub/defconfig | 1 - .../mrf24j40-starpoint/defconfig | 1 - configs/clicker2-stm32/xbee-6lowpan/defconfig | 1 - configs/freedom-k66f/netnsh/defconfig | 1 - configs/freedom-k66f/nsh/defconfig | 1 - configs/lc823450-xgevk/bt/defconfig | 1 - configs/lc823450-xgevk/krndis/defconfig | 1 - configs/lc823450-xgevk/rndis/defconfig | 1 - configs/lpcxpresso-lpc54628/README.txt | 1 - configs/mikroe-stm32f4/fulldemo/defconfig | 1 - configs/mikroe-stm32f4/kostest/defconfig | 1 - configs/olimexino-stm32/smallnsh/defconfig | 1 - .../mrf24j40-starhub/defconfig | 1 - .../samv71-xult/mrf24j40-starhub/defconfig | 1 - configs/stm32f4discovery/hciuart/defconfig | 1 - configs/stm32f746-ws/nsh/defconfig | 1 - include/nuttx/wqueue.h | 28 +-------- libs/libc/wqueue/Kconfig | 7 --- libs/libc/wqueue/work_usrthread.c | 33 +++++----- libs/libc/wqueue/wqueue.h | 3 +- sched/Kconfig | 18 ------ sched/wqueue/kwork_hpthread.c | 15 ++--- sched/wqueue/kwork_lpthread.c | 15 ++--- sched/wqueue/kwork_process.c | 58 +++++++---------- sched/wqueue/wqueue.h | 6 +- 30 files changed, 82 insertions(+), 184 deletions(-) diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index c51731e543..5dab69d992 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -12,7 +12,7 @@

NuttX RTOS Porting Guide

-

Last Updated: August 10, 2018

+

Last Updated: August 25, 2018

@@ -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)

Device Driver Bottom Half. - 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 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 bottom half 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). +

+

+ Thread Pool. + The work queues can be configured to support multiple, low-priority threads. This is essentially a thread pool 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). +

+

+ 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.

Compared to the Low Priority Kernel Work Queue. - 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 priority inheritance (if <config> CONFIG_PRIORITY_INHERITANCE 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 priority inheritance (if CONFIG_PRIORITY_INHERITANCE=y is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client.

Configuration Options. @@ -3021,11 +3029,12 @@ typedef uint32_t wdparm_t;

  • CONFIG_SCHED_HPWORK. Enables the hight priority work queue.
  • +
  • CONFIG_SCHED_HPNTHREADS. + The number of threads in the high-priority queue's 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 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.
  • CONFIG_SCHED_HPWORKSTACKSIZE. The stack size allocated for the worker thread in bytes. Default: 2048.
  • @@ -3047,30 +3056,19 @@ typedef uint32_t wdparm_t;

    Compared to the High Priority Work Queue. - 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 bottom half. 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 bottom half. + 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: +

    +

    Priority Inheritance. + The lower priority worker thread(s) support priority inheritance (if <config> CONFIG_PRIORITY_INHERITANCE is also selected): The priority of the lower priority worker thread can then be adjusted to match the highest priority client. +

    +
    + NOTE: This priority inheritance feature is not automatic. The lower priority worker thread will always a fixed priority unless additional logic implements that calls lpwork_boostpriority() to raise the priority of the lower priority worker thread (typically called before scheduling the work) and then calls 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 must run at a very high, fixed priority. Typically, it should be the highest priority thread in your system.

    -

    Configuration Options.

    @@ -3079,16 +3077,13 @@ typedef uint32_t wdparm_t; If CONFIG_SCHED_LPWORK is selected then a lower-priority work queue will be enabled.
  • CONFIG_SCHED_LPNTHREADS. - 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
  • CONFIG_SCHED_LPWORKPRIORITY. 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.
  • CONFIG_SCHED_LPWORKPRIOMAX. - The maximum execution priority of the lower priority worker thread. Lower priority worker threads will be started at CONFIG_SCHED_LPWORKPRIORITY but their priority may be boosted due to priority inheritance. The boosted priority of the low priority worker thread will not, however, ever exceedCONFIG_SCHED_LPWORKPRIOMAX. 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. -
  • -
  • CONFIG_SCHED_LPWORKPERIOD. - 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 CONFIG_SCHED_LPWORKPRIORITY but their priority may be boosted due to priority inheritance. The boosted priority of the low priority worker thread will not, however, ever exceed CONFIG_SCHED_LPWORKPRIOMAX. 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.
  • CONFIG_SCHED_LPWORKSTACKSIZE. 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.
  • CONFIG_LIB_USRWORKPRIORITY. The execution priority of the user-mode priority worker thread. Default: 100 -
  • CONFIG_LIB_USRWORKPERIOD - How often the lower priority worker thread is awakened in units of microseconds. Default: 100*1000 (100 MS).
  • CONFIG_LIB_USRWORKSTACKSIZE. The stack size allocated for the lower priority worker thread. Default: 2048. diff --git a/configs/b-l475e-iot01a/spirit-6lowpan/defconfig b/configs/b-l475e-iot01a/spirit-6lowpan/defconfig index 7d7a6c0c21..0c1bcf905d 100644 --- a/configs/b-l475e-iot01a/spirit-6lowpan/defconfig +++ b/configs/b-l475e-iot01a/spirit-6lowpan/defconfig @@ -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 diff --git a/configs/b-l475e-iot01a/spirit-starhub/defconfig b/configs/b-l475e-iot01a/spirit-starhub/defconfig index 88c8a2da80..52cd7f2a69 100644 --- a/configs/b-l475e-iot01a/spirit-starhub/defconfig +++ b/configs/b-l475e-iot01a/spirit-starhub/defconfig @@ -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 diff --git a/configs/b-l475e-iot01a/spirit-starpoint/defconfig b/configs/b-l475e-iot01a/spirit-starpoint/defconfig index 1921381f42..3029bd1d3c 100644 --- a/configs/b-l475e-iot01a/spirit-starpoint/defconfig +++ b/configs/b-l475e-iot01a/spirit-starpoint/defconfig @@ -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 diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig index 483e192cb8..7394e0ad12 100644 --- a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig @@ -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 diff --git a/configs/clicker2-stm32/mrf24j40-starhub/defconfig b/configs/clicker2-stm32/mrf24j40-starhub/defconfig index 71c1968a2c..61c8e42196 100644 --- a/configs/clicker2-stm32/mrf24j40-starhub/defconfig +++ b/configs/clicker2-stm32/mrf24j40-starhub/defconfig @@ -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 diff --git a/configs/clicker2-stm32/mrf24j40-starpoint/defconfig b/configs/clicker2-stm32/mrf24j40-starpoint/defconfig index 6c6bb42238..8b52de4bc4 100644 --- a/configs/clicker2-stm32/mrf24j40-starpoint/defconfig +++ b/configs/clicker2-stm32/mrf24j40-starpoint/defconfig @@ -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 diff --git a/configs/clicker2-stm32/xbee-6lowpan/defconfig b/configs/clicker2-stm32/xbee-6lowpan/defconfig index b717f73d1e..b3b87e4a8a 100644 --- a/configs/clicker2-stm32/xbee-6lowpan/defconfig +++ b/configs/clicker2-stm32/xbee-6lowpan/defconfig @@ -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 diff --git a/configs/freedom-k66f/netnsh/defconfig b/configs/freedom-k66f/netnsh/defconfig index 1bb2557624..2af3cb7c95 100644 --- a/configs/freedom-k66f/netnsh/defconfig +++ b/configs/freedom-k66f/netnsh/defconfig @@ -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 diff --git a/configs/freedom-k66f/nsh/defconfig b/configs/freedom-k66f/nsh/defconfig index 272933e657..ee263ecf05 100644 --- a/configs/freedom-k66f/nsh/defconfig +++ b/configs/freedom-k66f/nsh/defconfig @@ -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 diff --git a/configs/lc823450-xgevk/bt/defconfig b/configs/lc823450-xgevk/bt/defconfig index d61d4bba7f..a6aa231f5a 100644 --- a/configs/lc823450-xgevk/bt/defconfig +++ b/configs/lc823450-xgevk/bt/defconfig @@ -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 diff --git a/configs/lc823450-xgevk/krndis/defconfig b/configs/lc823450-xgevk/krndis/defconfig index 78af095ba9..41f2a1d890 100644 --- a/configs/lc823450-xgevk/krndis/defconfig +++ b/configs/lc823450-xgevk/krndis/defconfig @@ -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 diff --git a/configs/lc823450-xgevk/rndis/defconfig b/configs/lc823450-xgevk/rndis/defconfig index 5a7e41716a..524d18adba 100644 --- a/configs/lc823450-xgevk/rndis/defconfig +++ b/configs/lc823450-xgevk/rndis/defconfig @@ -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 diff --git a/configs/lpcxpresso-lpc54628/README.txt b/configs/lpcxpresso-lpc54628/README.txt index c9b3cbb524..97d17d4a38 100644 --- a/configs/lpcxpresso-lpc54628/README.txt +++ b/configs/lpcxpresso-lpc54628/README.txt @@ -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 diff --git a/configs/mikroe-stm32f4/fulldemo/defconfig b/configs/mikroe-stm32f4/fulldemo/defconfig index 6e20b899ee..19e40ec6b9 100644 --- a/configs/mikroe-stm32f4/fulldemo/defconfig +++ b/configs/mikroe-stm32f4/fulldemo/defconfig @@ -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 diff --git a/configs/mikroe-stm32f4/kostest/defconfig b/configs/mikroe-stm32f4/kostest/defconfig index 77f8ceee30..65a942d3db 100644 --- a/configs/mikroe-stm32f4/kostest/defconfig +++ b/configs/mikroe-stm32f4/kostest/defconfig @@ -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 diff --git a/configs/olimexino-stm32/smallnsh/defconfig b/configs/olimexino-stm32/smallnsh/defconfig index 1245c40237..392e5ada44 100644 --- a/configs/olimexino-stm32/smallnsh/defconfig +++ b/configs/olimexino-stm32/smallnsh/defconfig @@ -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 diff --git a/configs/same70-xplained/mrf24j40-starhub/defconfig b/configs/same70-xplained/mrf24j40-starhub/defconfig index ebc0079cb1..1f629fe9bc 100644 --- a/configs/same70-xplained/mrf24j40-starhub/defconfig +++ b/configs/same70-xplained/mrf24j40-starhub/defconfig @@ -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 diff --git a/configs/samv71-xult/mrf24j40-starhub/defconfig b/configs/samv71-xult/mrf24j40-starhub/defconfig index a8ceffb2dd..3ff7ecb263 100644 --- a/configs/samv71-xult/mrf24j40-starhub/defconfig +++ b/configs/samv71-xult/mrf24j40-starhub/defconfig @@ -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 diff --git a/configs/stm32f4discovery/hciuart/defconfig b/configs/stm32f4discovery/hciuart/defconfig index f1e725c7f9..9ba279f823 100644 --- a/configs/stm32f4discovery/hciuart/defconfig +++ b/configs/stm32f4discovery/hciuart/defconfig @@ -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 diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 7eb249de23..c0e91057eb 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -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 diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h index 1566638ce9..029d9b8b92 100644 --- a/include/nuttx/wqueue.h +++ b/include/nuttx/wqueue.h @@ -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 * * 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 diff --git a/libs/libc/wqueue/Kconfig b/libs/libc/wqueue/Kconfig index e6c8a0a5e6..d9b7d0dd76 100644 --- a/libs/libc/wqueue/Kconfig +++ b/libs/libc/wqueue/Kconfig @@ -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 diff --git a/libs/libc/wqueue/work_usrthread.c b/libs/libc/wqueue/work_usrthread.c index c4b167952d..8918ccc9ac 100644 --- a/libs/libc/wqueue/work_usrthread.c +++ b/libs/libc/wqueue/work_usrthread.c @@ -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 * * 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 */ diff --git a/libs/libc/wqueue/wqueue.h b/libs/libc/wqueue/wqueue.h index d823f555c0..2079abc6df 100644 --- a/libs/libc/wqueue/wqueue.h +++ b/libs/libc/wqueue/wqueue.h @@ -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 * * 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) */ }; diff --git a/sched/Kconfig b/sched/Kconfig index 0be2069dd8..498a8fd362 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -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 diff --git a/sched/wqueue/kwork_hpthread.c b/sched/wqueue/kwork_hpthread.c index 8ba3ba5ae2..58af3e3bb4 100644 --- a/sched/wqueue/kwork_hpthread.c +++ b/sched/wqueue/kwork_hpthread.c @@ -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. */ diff --git a/sched/wqueue/kwork_lpthread.c b/sched/wqueue/kwork_lpthread.c index 8da868015d..4ae6ca32ff 100644 --- a/sched/wqueue/kwork_lpthread.c +++ b/sched/wqueue/kwork_lpthread.c @@ -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. */ diff --git a/sched/wqueue/kwork_process.c b/sched/wqueue/kwork_process.c index 664cbb0e0e..00fda302ce 100644 --- a/sched/wqueue/kwork_process.c +++ b/sched/wqueue/kwork_process.c @@ -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); diff --git a/sched/wqueue/wqueue.h b/sched/wqueue/wqueue.h index a84550a6e1..56b0f2ab87 100644 --- a/sched/wqueue/wqueue.h +++ b/sched/wqueue/wqueue.h @@ -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 */