diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-14 18:58:21 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-14 18:58:21 +0000 |
commit | 78cbcfd2a16c0cf3763173ce0a14d656bede0135 (patch) | |
tree | 5fd6d76721ba77adb12c7fc265befb5cf264329f /nuttx/sched | |
parent | 9daf318dc8fbefa6d41c739fa53baa155b31887f (diff) | |
download | px4-nuttx-78cbcfd2a16c0cf3763173ce0a14d656bede0135.tar.gz px4-nuttx-78cbcfd2a16c0cf3763173ce0a14d656bede0135.tar.bz2 px4-nuttx-78cbcfd2a16c0cf3763173ce0a14d656bede0135.zip |
Add 8052 IRQ test; Fix places where IDLE task could try to wait on semaphoresnuttx-1.1
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@61 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/sched')
-rw-r--r-- | nuttx/sched/getpid.c | 2 | ||||
-rw-r--r-- | nuttx/sched/os_internal.h | 22 | ||||
-rw-r--r-- | nuttx/sched/os_start.c | 63 | ||||
-rw-r--r-- | nuttx/sched/sched_free.c | 7 |
4 files changed, 55 insertions, 39 deletions
diff --git a/nuttx/sched/getpid.c b/nuttx/sched/getpid.c index a68ce896a..3bd9495b6 100644 --- a/nuttx/sched/getpid.c +++ b/nuttx/sched/getpid.c @@ -80,5 +80,5 @@ pid_t getpid(void) * ready-to-run task list */ - return ((_TCB*)g_readytorun.head)->pid; + return ((FAR _TCB*)g_readytorun.head)->pid; } diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h index 0fa7172b5..85dda8c96 100644 --- a/nuttx/sched/os_internal.h +++ b/nuttx/sched/os_internal.h @@ -134,8 +134,8 @@ typedef struct pidhash_s pidhash_t; struct tasklist_s { - DSEG dq_queue_t *list; /* Pointer to the task list */ - boolean prioritized; /* TRUE if the list is prioritized */ + DSEG volatile dq_queue_t *list; /* Pointer to the task list */ + boolean prioritized; /* TRUE if the list is prioritized */ }; typedef struct tasklist_s tasklist_t; @@ -159,7 +159,7 @@ typedef struct tasklist_s tasklist_t; * list is always the idle task. */ -extern dq_queue_t g_readytorun; +extern volatile dq_queue_t g_readytorun; /* This is the list of all tasks that are ready-to-run, but * cannot be placed in the g_readytorun list because: (1) They @@ -168,16 +168,16 @@ extern dq_queue_t g_readytorun; * disabled pre-emption. */ -extern dq_queue_t g_pendingtasks; +extern volatile dq_queue_t g_pendingtasks; /* This is the list of all tasks that are blocked waiting for a semaphore */ -extern dq_queue_t g_waitingforsemaphore; +extern volatile dq_queue_t g_waitingforsemaphore; /* This is the list of all tasks that are blocked waiting for a signal */ #ifndef CONFIG_DISABLE_SIGNALS -extern dq_queue_t g_waitingforsignal; +extern volatile dq_queue_t g_waitingforsignal; #endif /* This is the list of all tasks that are blocked waiting for a message @@ -185,7 +185,7 @@ extern dq_queue_t g_waitingforsignal; */ #ifndef CONFIG_DISABLE_MQUEUE -extern dq_queue_t g_waitingformqnotempty; +extern volatile dq_queue_t g_waitingformqnotempty; #endif /* This is the list of all tasks that are blocked waiting for a message @@ -193,14 +193,14 @@ extern dq_queue_t g_waitingformqnotempty; */ #ifndef CONFIG_DISABLE_MQUEUE -extern dq_queue_t g_waitingformqnotfull; +extern volatile dq_queue_t g_waitingformqnotfull; #endif /* This the list of all tasks that have been initialized, but not yet * activated. NOTE: This is the only list that is not prioritized. */ -extern dq_queue_t g_inactivetasks; +extern volatile dq_queue_t g_inactivetasks; /* This is the list of dayed memory deallocations that need to be handled * within the IDLE loop. These deallocations get queued by sched_free() @@ -208,11 +208,11 @@ extern dq_queue_t g_inactivetasks; * handler. */ -extern sq_queue_t g_delayeddeallocations; +extern volatile sq_queue_t g_delayeddeallocations; /* This is the value of the last process ID assigned to a task */ -extern pid_t g_lastpid; +extern volatile pid_t g_lastpid; /* The following hash table is used for two things: * diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c index 9036f17bd..2c5da51a2 100644 --- a/nuttx/sched/os_start.c +++ b/nuttx/sched/os_start.c @@ -86,7 +86,7 @@ * list is always the idle task. */ -dq_queue_t g_readytorun; +volatile dq_queue_t g_readytorun; /* This is the list of all tasks that are ready-to-run, but * cannot be placed in the g_readytorun list because: (1) They @@ -95,16 +95,16 @@ dq_queue_t g_readytorun; * disabled pre-emption. */ -dq_queue_t g_pendingtasks; +volatile dq_queue_t g_pendingtasks; /* This is the list of all tasks that are blocked waiting for a semaphore */ -dq_queue_t g_waitingforsemaphore; +volatile dq_queue_t g_waitingforsemaphore; /* This is the list of all tasks that are blocked waiting for a signal */ #ifndef CONFIG_DISABLE_SIGNALS -dq_queue_t g_waitingforsignal; +volatile dq_queue_t g_waitingforsignal; #endif /* This is the list of all tasks that are blocked waiting for a message @@ -112,7 +112,7 @@ dq_queue_t g_waitingforsignal; */ #ifndef CONFIG_DISABLE_MQUEUE -dq_queue_t g_waitingformqnotempty; +volatile dq_queue_t g_waitingformqnotempty; #endif /* This is the list of all tasks that are blocked waiting for a message @@ -120,14 +120,14 @@ dq_queue_t g_waitingformqnotempty; */ #ifndef CONFIG_DISABLE_MQUEUE -dq_queue_t g_waitingformqnotfull; +volatile dq_queue_t g_waitingformqnotfull; #endif /* This the list of all tasks that have been initialized, but not yet * activated. NOTE: This is the only list that is not prioritized. */ -dq_queue_t g_inactivetasks; +volatile dq_queue_t g_inactivetasks; /* This is the list of dayed memory deallocations that need to be handled * within the IDLE loop. These deallocations get queued by sched_free() @@ -135,11 +135,11 @@ dq_queue_t g_inactivetasks; * handler. */ -sq_queue_t g_delayeddeallocations; +volatile sq_queue_t g_delayeddeallocations; /* This is the value of the last process ID assigned to a task */ -pid_t g_lastpid; +volatile pid_t g_lastpid; /* The following hash table is used for two things: * @@ -420,22 +420,35 @@ void os_start(void) dbg("Beginning Idle Loop\n"); for (;;) { - /* Check if there is anything in the delayed deallocation list. */ - - while (g_delayeddeallocations.head) - { - /* Remove the first delayed deallocation. */ - - irqstate_t saved_state = irqsave(); - void *address = (void*)sq_remfirst(&g_delayeddeallocations); - irqrestore(saved_state); - - /* Then deallocate it */ - - if (address) sched_free(address); - } - - /* Perform idle state operations */ + /* Check if there is anything in the delayed deallocation list. + * If there is deallocate it now. 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 -- and this should be possible because + * since we are running, no other task is! + */ + + if (mm_trysemaphore() == 0) + { + while (g_delayeddeallocations.head) + { + /* Remove the first delayed deallocation. */ + + irqstate_t saved_state = irqsave(); + void *address = (void*)sq_remfirst(&g_delayeddeallocations); + irqrestore(saved_state); + + /* Then deallocate it */ + + if (address) + { + sched_free(address); + } + } + mm_givesemaphore(); + } + + /* Perform any processor-specific idle state operations */ up_idle(); } diff --git a/nuttx/sched/sched_free.c b/nuttx/sched/sched_free.c index 96292426e..832e71082 100644 --- a/nuttx/sched/sched_free.c +++ b/nuttx/sched/sched_free.c @@ -83,10 +83,12 @@ void sched_free(FAR void *address) { /* Check if this is an attempt to deallocate memory from - * an exception handler. + * an exception handler. If this function is called from the + * IDLE task, then we must have exclusive access to the memory + * manager to do this. */ - if (up_interrupt_context()) + if (up_interrupt_context() || mm_trysemaphore() != 0) { /* Yes.. Delay the deallocation until a more appropriate time. */ @@ -99,6 +101,7 @@ void sched_free(FAR void *address) /* No.. just deallocate the memory now. */ kfree(address); + mm_givesemaphore(); } } |