summaryrefslogtreecommitdiff
path: root/nuttx/libc
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-10-10 13:21:37 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-10-10 13:21:37 -0600
commitf1ce005747fef1426ddc6a6564e78429afd66455 (patch)
treee34baca7321f77a62ab78e42f319ff8fc5fc594c /nuttx/libc
parent7861ae6281ce92c2dde2909f78474f1d98393205 (diff)
downloadnuttx-f1ce005747fef1426ddc6a6564e78429afd66455.tar.gz
nuttx-f1ce005747fef1426ddc6a6564e78429afd66455.tar.bz2
nuttx-f1ce005747fef1426ddc6a6564e78429afd66455.zip
Add support for delays of different durations in work queue processing
Diffstat (limited to 'nuttx/libc')
-rw-r--r--nuttx/libc/Kconfig25
-rw-r--r--nuttx/libc/wqueue/work_process.c34
-rw-r--r--nuttx/libc/wqueue/work_queue.c2
-rw-r--r--nuttx/libc/wqueue/work_signal.c2
-rw-r--r--nuttx/libc/wqueue/work_usrthread.c18
5 files changed, 49 insertions, 32 deletions
diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig
index eba38e0b6..d899bae0d 100644
--- a/nuttx/libc/Kconfig
+++ b/nuttx/libc/Kconfig
@@ -421,7 +421,7 @@ if SCHED_HPWORK
config SCHED_WORKPRIORITY
int "High priority worker thread priority"
- default 192
+ default 224
---help---
The execution priority of the higher priority worker thread.
@@ -440,10 +440,14 @@ config SCHED_WORKPRIORITY
config SCHED_WORKPERIOD
int "High priority worker thread period"
- default 50000
+ default 100000 if SCHED_LPWORK
+ default 50000 if !SCHED_LPWORK
---help---
How often the worker thread checks for work in units of microseconds.
- Default: 50*1000 (50 MS).
+ 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"
@@ -452,6 +456,8 @@ config SCHED_WORKSTACKSIZE
---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
@@ -533,7 +539,6 @@ config SCHED_LPWORKSTACKSIZE
The stack size allocated for the lower priority worker thread. Default: 2K.
endif # SCHED_LPWORK
-endif # SCHED_HPWORK
if BUILD_PROTECTED
@@ -545,20 +550,20 @@ config SCHED_USRWORK
if SCHED_USRWORK
-config SCHED_LPWORKPRIORITY
+config SCHED_USRWORKPRIORITY
int "User mode priority worker thread priority"
- default 50
+ default 100
---help---
The execution priority of the lopwer priority worker thread. Default: 192
-config SCHED_LPWORKPERIOD
+config SCHED_USRWORKPERIOD
int "User mode worker thread period"
- default 50000
+ default 100000
---help---
How often the lower priority worker thread checks for work in units
- of microseconds. Default: 50*1000 (50 MS).
+ of microseconds. Default: 100*1000 (100 MS).
-config SCHED_LPWORKSTACKSIZE
+config SCHED_USRWORKSTACKSIZE
int "User mode worker thread stack size"
default 2048
---help---
diff --git a/nuttx/libc/wqueue/work_process.c b/nuttx/libc/wqueue/work_process.c
index d55bf1ea6..92cfd5c87 100644
--- a/nuttx/libc/wqueue/work_process.c
+++ b/nuttx/libc/wqueue/work_process.c
@@ -64,9 +64,9 @@
# define WORK_CLOCK CLOCK_REALTIME
#endif
-/* The work poll period is in system ticks. */
-
-#define WORKPERIOD_TICKS (CONFIG_SCHED_WORKPERIOD / USEC_PER_TICK)
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
/****************************************************************************
* Private Type Declarations
@@ -121,7 +121,7 @@ void work_process(FAR struct wqueue_s *wqueue)
* we process items in the work list.
*/
- next = WORKPERIOD_TICKS;
+ next = wqueue->delay;
flags = irqsave();
/* Get the time that we started this polling cycle in clock ticks. */
@@ -221,18 +221,28 @@ void work_process(FAR struct wqueue_s *wqueue)
}
}
- /* There is no work to be performed now. Check if we need to delay or if we have
- * already exceed the duration of the polling period.
- */
+ /* Get the delay (in clock ticks) since we started the sampling */
- if (next < WORKPERIOD_TICKS)
+ elapsed = clock_systimer() - work->qtime;
+ if (elapsed <= wqueue->delay)
{
- /* 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.
+ /* 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.
*/
- usleep(next * USEC_PER_TICK);
+ remaining = wqueue->delay - elapsed;
+ next = MIN(next, remaining);
+ if (next > 0)
+ {
+ /* 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.
+ */
+
+ usleep(next * USEC_PER_TICK);
+ }
}
irqrestore(flags);
diff --git a/nuttx/libc/wqueue/work_queue.c b/nuttx/libc/wqueue/work_queue.c
index edfbb166e..3abba1599 100644
--- a/nuttx/libc/wqueue/work_queue.c
+++ b/nuttx/libc/wqueue/work_queue.c
@@ -127,7 +127,7 @@ int work_qqueue(FAR struct wqueue_s *wqueue, FAR struct work_s *work,
work->qtime = clock_systimer(); /* Time work queued */
dq_addlast((FAR dq_entry_t *)work, &wqueue->q);
- kill(wqueue->pid, SIGWORK); /* Wake up the worker thread */
+ kill(wqueue->pid[0], SIGWORK); /* Wake up the worker thread */
irqrestore(flags);
return OK;
diff --git a/nuttx/libc/wqueue/work_signal.c b/nuttx/libc/wqueue/work_signal.c
index 2d6b9e238..288c89877 100644
--- a/nuttx/libc/wqueue/work_signal.c
+++ b/nuttx/libc/wqueue/work_signal.c
@@ -96,7 +96,7 @@ int work_signal(int qid)
{
/* Signal the worker thread */
- ret = kill(g_usrwork.pid, SIGWORK);
+ ret = kill(g_usrwork.pid[0], SIGWORK);
if (ret < 0)
{
int errcode = errno;
diff --git a/nuttx/libc/wqueue/work_usrthread.c b/nuttx/libc/wqueue/work_usrthread.c
index 4ab1f4468..dfa67735f 100644
--- a/nuttx/libc/wqueue/work_usrthread.c
+++ b/nuttx/libc/wqueue/work_usrthread.c
@@ -44,6 +44,7 @@
#include <debug.h>
#include <nuttx/wqueue.h>
+#include <nuttx/clock.h>
#if defined(CONFIG_SCHED_WORKQUEUE) && defined(CONFIG_SCHED_USRWORK) && \
!defined(__KERNEL__)
@@ -130,20 +131,21 @@ int work_usrstart(void)
{
/* Initialize work queue data structures */
+ g_usrwork.delay = CONFIG_SCHED_USRWORKPERIOD / USEC_PER_TICK;
dq_init(&g_usrwork.q);
/* Start a user-mode worker thread for use by applications. */
svdbg("Starting user-mode worker thread\n");
- g_usrwork.pid = task_create("uwork",
- CONFIG_SCHED_USRWORKPRIORITY,
- CONFIG_SCHED_USRWORKSTACKSIZE,
- (main_t)work_usrthread,
- (FAR char * const *)NULL);
+ g_usrwork.pid[0] = task_create("uwork",
+ CONFIG_SCHED_USRWORKPRIORITY,
+ CONFIG_SCHED_USRWORKSTACKSIZE,
+ (main_t)work_usrthread,
+ (FAR char * const *)NULL);
- DEBUGASSERT(g_usrwork.pid > 0);
- if (g_usrwork.pid < 0)
+ DEBUGASSERT(g_usrwork.pid[0] > 0);
+ if (g_usrwork.pid[0] < 0)
{
int errcode = errno;
DEBUGASSERT(errcode > 0);
@@ -152,7 +154,7 @@ int work_usrstart(void)
return -errcode;
}
- return g_usrwork.pid;
+ return g_usrwork.pid[0];
}
#endif /* CONFIG_SCHED_WORKQUEUE && CONFIG_SCHED_USRWORK && !__KERNEL__*/