Skip to content

Commit

Permalink
Decouple the user-space work queue from the kernel space work queues
Browse files Browse the repository at this point in the history
  • Loading branch information
gregory-nutt committed Oct 11, 2014
1 parent c38b814 commit 9292e3d
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 205 deletions.
2 changes: 1 addition & 1 deletion configs/mikroe-stm32f4/kernel/up_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =

/* User-space work queue support (declared in include/nuttx/wqueue.h) */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
.work_usrstart = work_usrstart,
#endif
};
Expand Down
2 changes: 1 addition & 1 deletion configs/open1788/kernel/up_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =

/* User-space work queue support (declared in include/nuttx/wqueue.h) */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
.work_usrstart = work_usrstart,
#endif
};
Expand Down
2 changes: 1 addition & 1 deletion configs/sam3u-ek/kernel/up_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =

/* User-space work queue support (declared in include/nuttx/wqueue.h) */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
.work_usrstart = work_usrstart,
#endif
};
Expand Down
2 changes: 1 addition & 1 deletion configs/stm3240g-eval/kernel/up_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =

/* User-space work queue support (declared in include/nuttx/wqueue.h) */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
.work_usrstart = work_usrstart,
#endif
};
Expand Down
2 changes: 1 addition & 1 deletion configs/stm32f4discovery/kernel/up_userspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) =

/* User-space work queue support (declared in include/nuttx/wqueue.h) */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
.work_usrstart = work_usrstart,
#endif
};
Expand Down
2 changes: 1 addition & 1 deletion include/nuttx/userspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ struct userspace_s

/* User-space work queue support */

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK)
#ifdef CONFIG_SCHED_USRWORK
int (*work_usrstart)(void);
#endif
};
Expand Down
24 changes: 11 additions & 13 deletions include/nuttx/wqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* CONFIG_SCHED_WORKQUEUE. Create a dedicated "worker" thread to
/* CONFIG_SCHED_WORKQUEUE. Not selectable. Set by the configuration system
* if either CONFIG_SCHED_HPWORK or CONFIG_SCHED_LPWORK are selected.
* CONFIG_SCHED_HPWORK. Create a dedicated "worker" thread to
* handle delayed processing from interrupt handlers. This feature
* is required for some drivers but, if there are not complaints,
* can be safely disabled. The worker thread also performs
* garbage collection -- completing any delayed memory deallocations
* from interrupt handlers. If the worker thread is disabled,
* then that clean will be performed by the IDLE thread instead
* (which runs at the lowest of priority and may not be appropriate
* if memory reclamation is of high priority). If CONFIG_SCHED_WORKQUEUE
* if memory reclamation is of high priority). If CONFIG_SCHED_HPWORK
* is enabled, then the following options can also be used:
* CONFIG_SCHED_HPWORK - Build the high priority work queue. To preserve
* legacy behavior, CONFIG_SCHED_HPWORK is assumed to be true in a flat
Expand All @@ -77,11 +79,10 @@
* CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up
* the worker thread. Default: 17
*
* CONFIG_SCHED_LPWORK. If CONFIG_SCHED_WORKQUEUE is defined, then a single
* work queue is created by default. If CONFIG_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)
* CONFIG_SCHED_LPWORK. If CONFIG_SCHED_LPWORK is selected then a lower-
* priority work queue will be created. This lower priority work queue
* is better suited for more extended processing (such as file system
* clean-up operations)
* CONFIG_SCHED_LPNTHREADS - The number of thread in the low-priority queue's
* thread pool. Default: 1
* CONFIG_SCHED_LPWORKPRIORITY - The minimum execution priority of the lower
Expand Down Expand Up @@ -119,10 +120,7 @@

# undef CONFIG_SCHED_HPWORK
# undef CONFIG_SCHED_LPWORK

# ifndef CONFIG_SCHED_USRWORK
# undef CONFIG_SCHED_WORKQUEUE
# endif
# undef CONFIG_SCHED_WORKQUEUE

/* User-space worker threads are not built in a kernel build when we are
* building the kernel-space libraries (but we still need to know that it
Expand All @@ -144,7 +142,7 @@
# undef CONFIG_SCHED_USRWORK
#endif

#ifdef CONFIG_SCHED_WORKQUEUE
#if defined(CONFIG_SCHED_WORKQUEUE) || defined(CONFIG_SCHED_USRWORK)

/* High priority, kernel work queue configuration ***************************/

Expand Down Expand Up @@ -471,5 +469,5 @@ void lpwork_restorepriority(uint8_t reqprio);
#endif

#endif /* __ASSEMBLY__ */
#endif /* CONFIG_SCHED_WORKQUEUE */
#endif /* CONFIG_SCHED_WORKQUEUE || CONFIG_SCHED_USRWORK */
#endif /* __INCLUDE_NUTTX_WQUEUE_H */
166 changes: 3 additions & 163 deletions libc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -393,174 +393,15 @@ endif # ARCH_OPTIMIZED_FUNCTIONS

comment "Non-standard Library Support"

config SCHED_WORKQUEUE
bool "Enable worker thread"
default n
depends on !DISABLE_SIGNALS
---help---
Create a dedicated "worker" thread to handle delayed processing from interrupt
handlers. This feature is required for some drivers but, if there are no
complaints, can be safely disabled. The worker thread also performs
garbage collection -- completing any delayed memory deallocations from
interrupt handlers. If the worker thread is disabled, then that clean up will
be performed by the IDLE thread instead (which runs at the lowest of priority
and may not be appropriate if memory reclamation is of high priority).

if SCHED_WORKQUEUE

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_HPWORK

config SCHED_WORKPRIORITY
int "High priority worker thread priority"
default 224
---help---
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"
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_WORKSTACKSIZE
int "High priority worker thread stack size"
default 2048
---help---
The stack size allocated for the worker thread. Default: 2K.

endif # SCHED_HPWORK

config SCHED_LPWORK
bool "Low priority (kernel) worker thread"
default n
---help---
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, application oriented
processing (such as file system clean-up operations or asynchronous
I/O)

if SCHED_LPWORK

config SCHED_LPNTHREADS
int "Number of low-priority worker threads"
default 1 if !FS_AIO
default 4 if FS_AIO
---help---
This options selectes multiple, low-priority threads. This is
essentially a "thread pool" that provides multi-threaded service
of the low-priority work thread. This breaks the serialization
of the "queue" (hence, it is no longer a queue at all).

This options is 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 stalls in such cases.
Such behvior must be support for asynchronous I/O, AIO (for example).

config SCHED_LPWORKPRIORITY
int "Low priority worker thread priority"
default 50
---help---
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"
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
---help---
The stack size allocated for the lower priority worker thread. Default: 2K.

endif # SCHED_LPWORK

if BUILD_PROTECTED || BUILD_KERNEL

config SCHED_USRWORK
bool "User mode worker thread"
default n
depends on !DISABLE_SIGNALS
---help---
User space work queues can also be made available for deferred processing in the NuttX kernel build.
User space work queues can also be made available for deferred
processing in the NuttX kernel build.

if SCHED_USRWORK

Expand All @@ -585,7 +426,6 @@ config SCHED_USRWORKSTACKSIZE

endif # SCHED_USRWORK
endif # BUILD_PROTECTED
endif # SCHED_WORKQUEUE

config LIB_KBDCODEC
bool "Keyboard CODEC"
Expand Down
2 changes: 1 addition & 1 deletion libc/wqueue/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#
############################################################################

ifeq ($(CONFIG_SCHED_WORKQUEUE),y)
ifeq ($(CONFIG_SCHED_USRWORK),y)

# Add the work queue C files to the build

Expand Down
5 changes: 2 additions & 3 deletions libc/wqueue/work_cancel.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@

#include "wqueue/wqueue.h"

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK) && \
!defined(__KERNEL__)
#if defined(CONFIG_SCHED_USRWORK) && !defined(__KERNEL__)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -163,4 +162,4 @@ int work_cancel(int qid, FAR struct work_s *work)
}
}

#endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_USRWORK && !__KERNEL__ */
#endif /* CONFIG_SCHED_USRWORK && !__KERNEL__ */
5 changes: 2 additions & 3 deletions libc/wqueue/work_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@

#include "wqueue/wqueue.h"

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK) && \
!defined(__KERNEL__)
#if defined(CONFIG_SCHED_USRWORK) && !defined(__KERNEL__)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -136,4 +135,4 @@ void work_unlock(void)
#endif
}

#endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_USRWORK && !__KERNEL__*/
#endif /* CONFIG_SCHED_USRWORK && !__KERNEL__*/
5 changes: 2 additions & 3 deletions libc/wqueue/work_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@

#include "wqueue/wqueue.h"

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK) && \
!defined(__KERNEL__)
#if defined(CONFIG_SCHED_USRWORK) && !defined(__KERNEL__)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -175,4 +174,4 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker,
}
}

#endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_USRWORK && !__KERNEL__ */
#endif /* CONFIG_SCHED_USRWORK && !__KERNEL__ */
3 changes: 1 addition & 2 deletions libc/wqueue/work_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

#include "wqueue/wqueue.h"

#ifdef CONFIG_SCHED_WORKQUEUE
#if defined(CONFIG_SCHED_USRWORK) && !defined(__KERNEL__)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -113,4 +113,3 @@ int work_signal(int qid)
}

#endif /* CONFIG_SCHED_USRWORK && !__KERNEL__ */
#endif /* CONFIG_SCHED_WORKQUEUE */
5 changes: 2 additions & 3 deletions libc/wqueue/work_usrthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@

#include "wqueue/wqueue.h"

#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK) && \
!defined(__KERNEL__)
#if defined(CONFIG_SCHED_USRWORK) && !defined(__KERNEL__)

/****************************************************************************
* Pre-processor Definitions
Expand Down Expand Up @@ -404,4 +403,4 @@ int work_usrstart(void)
#endif
}

#endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_USRWORK && !__KERNEL__*/
#endif /* CONFIG_SCHED_USRWORK && !__KERNEL__*/
Loading

0 comments on commit 9292e3d

Please sign in to comment.