mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
Integrte work thread
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2232 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+1
-1
@@ -387,7 +387,7 @@ int rwb_initialize(FAR struct rwbuffer_s *rwb)
|
|||||||
rwb->wrbuffer = NULL;
|
rwb->wrbuffer = NULL;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_FS_READAHEAD
|
#ifdef CONFIG_FS_READAHEAD
|
||||||
DEBUGASSERT(rwb->rhnblocks > 0);
|
DEBUGASSERT(rwb->rhblocks > 0);
|
||||||
DEBUGASSERT(rwb->rhreload != NULL);
|
DEBUGASSERT(rwb->rhreload != NULL);
|
||||||
rwb->rhbuffer = NULL;
|
rwb->rhbuffer = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+16
-5
@@ -461,13 +461,24 @@ void os_start(void)
|
|||||||
sdbg("Beginning Idle Loop\n");
|
sdbg("Beginning Idle Loop\n");
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Peform garbage collection (if it is not being done by the worker
|
/* Perform garbage collection (if it is not being done by the worker
|
||||||
* thread. This cleans-up memory de-allocations that was queued
|
* thread). This cleans-up memory de-allocations that were queued
|
||||||
* because it could not be freed in that execution context (for
|
* because they could not be freed in that execution context (for
|
||||||
* example, if the memory was freed from an interrupt handler).
|
* example, if the memory was freed from an interrupt handler).
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_SCHED_WORKQEUE
|
|
||||||
sched_garbagecollection();
|
#ifndef CONFIG_SCHED_WORKQUEUE
|
||||||
|
/* We must have exclusive access to the memory manager to do this
|
||||||
|
* BUT the idle task cannot wait on a semaphore. So we only do
|
||||||
|
* the cleanup now if we can get the semaphore -- this should be
|
||||||
|
* possible because if the IDLE thread is running, no other task is!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (mm_trysemaphore() == 0)
|
||||||
|
{
|
||||||
|
sched_garbagecollection();
|
||||||
|
mm_givesemaphore();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Perform any processor-specific idle state operations */
|
/* Perform any processor-specific idle state operations */
|
||||||
|
|||||||
+19
-27
@@ -42,8 +42,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <nuttx/mm.h>
|
|
||||||
|
|
||||||
#include "os_internal.h"
|
#include "os_internal.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -93,35 +91,29 @@
|
|||||||
|
|
||||||
void sched_garbagecollection(void)
|
void sched_garbagecollection(void)
|
||||||
{
|
{
|
||||||
/* Check if there is anything in the delayed deallocation list. If there
|
irqstate_t flags;
|
||||||
* is deallocate it now. We must have exclusive access to the memory manager
|
void *address;
|
||||||
* to do this BUT the idle task cannot wait on a semaphore. So we only do
|
|
||||||
* the cleanup now if we can get the semaphore -- and this should be possible
|
|
||||||
* because if the IDLE thread is running, no other task is!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_WORKQUEUE
|
/* Test if the delayed deallocation queue is empty. No special protection
|
||||||
mm_takesemaphore();
|
* is needed because this is an atomic test.
|
||||||
#else
|
*/
|
||||||
if (mm_trysemaphore() == 0)
|
|
||||||
#endif
|
while (g_delayeddeallocations.head)
|
||||||
{
|
{
|
||||||
while (g_delayeddeallocations.head)
|
/* Remove the first delayed deallocation. This is not atomic and so
|
||||||
|
* we must disable interrupts around the queue operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
flags = irqsave();
|
||||||
|
address = (void*)sq_remfirst((FAR sq_queue_t*)&g_delayeddeallocations);
|
||||||
|
irqrestore(flags);
|
||||||
|
|
||||||
|
/* Then deallocate it. */
|
||||||
|
|
||||||
|
if (address)
|
||||||
{
|
{
|
||||||
/* Remove the first delayed deallocation. */
|
free(address);
|
||||||
|
|
||||||
irqstate_t saved_state = irqsave();
|
|
||||||
void *address = (void*)sq_remfirst((FAR sq_queue_t*)&g_delayeddeallocations);
|
|
||||||
irqrestore(saved_state);
|
|
||||||
|
|
||||||
/* Then deallocate it */
|
|
||||||
|
|
||||||
if (address)
|
|
||||||
{
|
|
||||||
free(address);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mm_givesemaphore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -101,8 +101,8 @@ int work_cancel(struct work_s *work)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
DEBUGASSERT(work->flink || (FAR dq_entry_t *)work == g_work.head);
|
DEBUGASSERT(work->dq.flink || (FAR dq_entry_t *)work == g_work.head);
|
||||||
DEBUGASSERT(work->blink || (FAR dq_entry_t *)work == g_work.tail);
|
DEBUGASSERT(work->dq.blink || (FAR dq_entry_t *)work == g_work.tail);
|
||||||
dq_rem((FAR dq_entry_t *)work, &g_work);
|
dq_rem((FAR dq_entry_t *)work, &g_work);
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
|
|||||||
+12
-8
@@ -113,7 +113,12 @@ int work_thread(int argc, char *argv[])
|
|||||||
|
|
||||||
usleep(CONFIG_SCHED_WORKPERIOD);
|
usleep(CONFIG_SCHED_WORKPERIOD);
|
||||||
|
|
||||||
/* First, clean-up any delayed memory deallocations */
|
/* First, perform garbage collection. This cleans-up memory de-allocations
|
||||||
|
* that were queued because they could not be freed in that execution
|
||||||
|
* context (for example, if the memory was freed from an interrupt handler).
|
||||||
|
* NOTE: If the work thread is disabled, this clean-up is performed by
|
||||||
|
* the IDLE thread (at a very, very lower priority).
|
||||||
|
*/
|
||||||
|
|
||||||
sched_garbagecollection();
|
sched_garbagecollection();
|
||||||
|
|
||||||
@@ -131,21 +136,20 @@ int work_thread(int argc, char *argv[])
|
|||||||
|
|
||||||
if (work->delay == 0 || g_system_timer - work->qtime > work->delay)
|
if (work->delay == 0 || g_system_timer - work->qtime > work->delay)
|
||||||
{
|
{
|
||||||
/* Remove the work at the head of the list. And re-enable
|
/* Remove the ready-to-execute work from the list */
|
||||||
* interrupts while the work is performed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(void)dq_remfirst(&g_work);
|
(void)dq_rem((struct dq_entry_s *)work, &g_work);
|
||||||
|
|
||||||
/* Do the work. Re-enable interrupts while the work is being
|
/* Do the work. Re-enable interrupts while the work is being
|
||||||
* performed... we don't have any idea how long that will take
|
* performed... we don't have any idea how long that will take!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
work->worker(work->arg);
|
work->worker(work->arg);
|
||||||
|
|
||||||
/* Now, unfortunately, since we re-enabled interrupts we have
|
/* Now, unfortunately, since we re-enabled interrupts we don't
|
||||||
* to start back at the head of the list.
|
* the state of the work list and we will have to start back at
|
||||||
|
* the head of the list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = irqsave();
|
flags = irqsave();
|
||||||
|
|||||||
Reference in New Issue
Block a user