summaryrefslogtreecommitdiff
path: root/nuttx/sched
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-14 18:58:21 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-14 18:58:21 +0000
commit78cbcfd2a16c0cf3763173ce0a14d656bede0135 (patch)
tree5fd6d76721ba77adb12c7fc265befb5cf264329f /nuttx/sched
parent9daf318dc8fbefa6d41c739fa53baa155b31887f (diff)
downloadpx4-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.c2
-rw-r--r--nuttx/sched/os_internal.h22
-rw-r--r--nuttx/sched/os_start.c63
-rw-r--r--nuttx/sched/sched_free.c7
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();
}
}