diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html index 1ce105c8f8..93c629fe51 100644 --- a/Documentation/NuttxPortingGuide.html +++ b/Documentation/NuttxPortingGuide.html @@ -2148,7 +2148,7 @@ extern void up_ledoff(int led);
  • CONFIG_SCHED_WORKPERIOD: How often the worker thread checks for - work. Default: 50 MS. + work in units of microseconds. Default: 50*1000 (50 MS).
  • CONFIG_SCHED_WORKSTACKSIZE: The stack size allocated for the worker diff --git a/configs/README.txt b/configs/README.txt index 6ccd836642..17c29286e4 100644 --- a/configs/README.txt +++ b/configs/README.txt @@ -256,7 +256,7 @@ defconfig -- This is a configuration file similar to the Linux CONFIG_SCHED_WORKPRIORITY - The execution priority of the worker thread. Default: 50 CONFIG_SCHED_WORKPERIOD - How often the worker thread checks for - work. Default: 50 MS. + work in units of microseconds. Default: 50*1000 (50 MS). CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker thread. Default: CONFIG_IDLETHREAD_STACKSIZE. CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up diff --git a/configs/stm3210e-eval/RIDE/defconfig b/configs/stm3210e-eval/RIDE/defconfig index 7e9a52b642..cc08dc9c01 100755 --- a/configs/stm3210e-eval/RIDE/defconfig +++ b/configs/stm3210e-eval/RIDE/defconfig @@ -307,7 +307,7 @@ CONFIG_HAVE_LIBM=n # CONFIG_SCHED_WORKPRIORITY - The execution priority of the worker # thread. Default: 50 # CONFIG_SCHED_WORKPERIOD - How often the worker thread checks for -# work. Default: 50 MS. +# work in units of microseconds. Default: 50*1000 (50 MS). # CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker # thread. Default: CONFIG_IDLETHREAD_STACKSIZE. # CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up @@ -340,7 +340,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_NXFLAT=n CONFIG_SCHED_WORKQUEUE=n CONFIG_SCHED_WORKPRIORITY=50 -CONFIG_SCHED_WORKPERIOD=50 +CONFIG_SCHED_WORKPERIOD=(50*1000) CONFIG_SCHED_WORKSTACKSIZE=1024 CONFIG_SIG_SIGWORK=4 diff --git a/configs/stm3210e-eval/nsh/defconfig b/configs/stm3210e-eval/nsh/defconfig index 19f682d908..5a41b5b1ee 100755 --- a/configs/stm3210e-eval/nsh/defconfig +++ b/configs/stm3210e-eval/nsh/defconfig @@ -317,7 +317,7 @@ CONFIG_HAVE_LIBM=n # CONFIG_SCHED_WORKPRIORITY - The execution priority of the worker # thread. Default: 50 # CONFIG_SCHED_WORKPERIOD - How often the worker thread checks for -# work. Default: 50 MS. +# work in units of microseconds. Default: 50*1000 (50 MS). # CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker # thread. Default: CONFIG_IDLETHREAD_STACKSIZE. # CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up @@ -349,7 +349,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_NXFLAT=n CONFIG_SCHED_WORKQUEUE=y CONFIG_SCHED_WORKPRIORITY=50 -CONFIG_SCHED_WORKPERIOD=50 +CONFIG_SCHED_WORKPERIOD=(50*1000) CONFIG_SCHED_WORKSTACKSIZE=1024 CONFIG_SIG_SIGWORK=4 diff --git a/configs/stm3210e-eval/ostest/defconfig b/configs/stm3210e-eval/ostest/defconfig index 45e416804a..0ea76f6cdf 100755 --- a/configs/stm3210e-eval/ostest/defconfig +++ b/configs/stm3210e-eval/ostest/defconfig @@ -319,7 +319,7 @@ CONFIG_HAVE_LIBM=n # CONFIG_SCHED_WORKPRIORITY - The execution priority of the worker # thread. Default: 50 # CONFIG_SCHED_WORKPERIOD - How often the worker thread checks for -# work. Default: 50 MS. +# work in units of microseconds. Default: 50*1000 (50 MS). # CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker # thread. Default: CONFIG_IDLETHREAD_STACKSIZE. # CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up @@ -351,7 +351,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_NXFLAT=n CONFIG_SCHED_WORKQUEUE=n CONFIG_SCHED_WORKPRIORITY=50 -CONFIG_SCHED_WORKPERIOD=50 +CONFIG_SCHED_WORKPERIOD=(50*1000) CONFIG_SCHED_WORKSTACKSIZE=1024 CONFIG_SIG_SIGWORK=4 diff --git a/configs/stm3210e-eval/usbserial/defconfig b/configs/stm3210e-eval/usbserial/defconfig index 6d7adf0c04..23910eb2d3 100755 --- a/configs/stm3210e-eval/usbserial/defconfig +++ b/configs/stm3210e-eval/usbserial/defconfig @@ -319,7 +319,7 @@ CONFIG_HAVE_LIBM=n # CONFIG_SCHED_WORKPRIORITY - The execution priority of the worker # thread. Default: 50 # CONFIG_SCHED_WORKPERIOD - How often the worker thread checks for -# work. Default: 50 MS. +# work in units of microseconds. Default: 50*1000 (50 MS). # CONFIG_SCHED_WORKSTACKSIZE - The stack size allocated for the worker # thread. Default: CONFIG_IDLETHREAD_STACKSIZE. # CONFIG_SIG_SIGWORK - The signal number that will be used to wake-up @@ -352,7 +352,7 @@ CONFIG_SDCLONE_DISABLE=y CONFIG_NXFLAT=n CONFIG_SCHED_WORKQUEUE=n CONFIG_SCHED_WORKPRIORITY=50 -CONFIG_SCHED_WORKPERIOD=50 +CONFIG_SCHED_WORKPERIOD=(50*1000) CONFIG_SCHED_WORKSTACKSIZE=1024 CONFIG_SIG_SIGWORK=4 diff --git a/sched/work_thread.c b/sched/work_thread.c index d1f415d777..1a772b6186 100755 --- a/sched/work_thread.c +++ b/sched/work_thread.c @@ -103,17 +103,24 @@ int work_thread(int argc, char *argv[]) volatile FAR struct work_s *work; worker_t worker; FAR void *arg; + uint32 elapsed; + uint32 remaining; + uint32 next; + int usec; irqstate_t flags; /* Loop forever */ + usec = CONFIG_SCHED_WORKPERIOD; + flags = irqsave(); for (;;) { /* Wait awhile to check the work list. We will wait here until either * the time elapses or until we are awakened by a signal. */ - usleep(CONFIG_SCHED_WORKPERIOD); + usleep(usec); + irqrestore(flags); /* First, perform garbage collection. This cleans-up memory de-allocations * that were queued because they could not be freed in that execution @@ -128,15 +135,19 @@ int work_thread(int argc, char *argv[]) * we process items in the work list. */ + next = CONFIG_SCHED_WORKPERIOD / USEC_PER_TICK; flags = irqsave(); work = (FAR struct work_s *)g_work.head; while (work) { /* Is this work ready? It is ready if there is no delay or if - * the delay has elapsed. + * the delay has elapsed. qtime is the time that the work was added + * to the work queue. It will always be greater than or equal to + * zero. Therefore a delay of zero will always execute immediately. */ - if (work->delay == 0 || g_system_timer - work->qtime > work->delay) + elapsed = g_system_timer - work->qtime; + if (elapsed >= work->delay) { /* Remove the ready-to-execute work from the list */ @@ -166,12 +177,27 @@ int work_thread(int argc, char *argv[]) } else { - /* This one is not ready, try the next in the list. */ + /* This one is not ready.. will it be ready before the next + * scheduled wakeup interval? + */ + + remaining = elapsed - work->delay; + if (remaining < next) + { + /* Yes.. Then schedule to wake up when the work is ready */ + + next = remaining; + } + + /* Then try the next in the list. */ work = (FAR struct work_s *)work->dq.flink; } } - irqrestore(flags); + + /* Now calculate the microsecond delay we should wait */ + + usec = next * USEC_PER_TICK; } return OK; /* To keep some compilers happy */